查看原文
其他

对比excel,用python获取时序数据中的日期与时间(分列)

道才 可以叫我才哥 2023-02-06

大家好,我是才哥。

今天下班回家,收到朋友的提问,他在处理日期类型数据时需要获取日期和时间,但是翻车了。。那么,我们这一期的答疑解惑就来介绍一下日常数据处理中常见的时间属性获取技巧吧!

当然,我这里说的最简单的方式其实应该是属于不熟悉的情况下最容易想到的方案,在1年前我就是这么处理的。

那就开搞吧!!

案例数据在后台回复 955 ,通过 答疑解惑文件夹领取。

目录:

  • 1. 常规的分列思路

    • 1.1. excel操作流程

    • 2.1. python操作流程

  • 2. pandas时间访问器


1. 常规的分列思路

熟悉excel操作的同学,应该比较常用分列操作。

1.1. excel操作流程

本节我们就先试试用excel来操作。

打开文件,选中数据区域,在菜单栏数据—>分列操作中进行设置,肉眼直观看应该是按照空格分列,但是选中发现有问题(没有反应)。

按空格分列存在问题

遇到上述情况,先不要慌,很有可能肉眼所见并非能用的分隔符,我们可以手动复制一下我们认为的“空格”然后粘贴到其他里。

拷贝分隔符

用上(就好使了)

复制分隔符用上

到这里,我们似乎大致知道这位朋友翻车的原因了,可能他用python分列时用的也是空格符号做的分隔符导致的,那么用python的分列操作在这种情况下应该怎么处理呢,我们继续往下看。

2.1. python操作流程

读取数据预览看下情况

import pandas as pd

df = pd.read_excel(r'.\data\时间处理案例数据.xlsx')
df.head()

再简单看看字段类型等

df.info()

可以看到两个字段都是object类型。

这里先看一下朋友操作的翻车过程:

翻车的处理

可以看到朋友的操作报错提示 ValueError,问题出在哪里呢?

答疑解惑时刻

一般来说,我会先打印单条数据看下情况

df['资源分配时间'][0]
'2021-09-01\xa016:50:56'

果然,我们发现其实肉眼所见的空格是\xa0,直接用空格" "用于分列自然就不行了。

我们通常所用的空格是\x20,是在标准ASCII可见字符0x20~0x7e范围内。

\xa0属于latin1(ISO/IEC_8859-1)中的扩展字符集字符,代表不间断空白符

所以,我们可以这样分列:

df['资源分配时间'].str.split('\xa0')
0 [2021-09-01, 16:50:56]
1 [2021-09-01, 16:50:56]
2 [2021-09-01, 16:50:56]
3 [2021-09-01, 16:50:56]
4 [2021-09-01, 16:50:56]
...
560 [2021-09-13, 21:05:14]
561 [2021-09-14, 09:33:02]
562 [2021-09-14, 09:33:02]
563 [2021-09-14, 10:26:42]
564 [2021-09-14, 10:29:58]
Name: 资源分配时间, Length: 565, dtype: object

当然,对于上面这个结果,按照朋友的操作切片选择也是不满足要求的,请看:

df['资源分配时间'].str.split('\xa0')[0]
['2021-09-01', '16:50:56']

那,如何实现需求呢?继续看,这里需要引入apply函数方法,调用一个切片处理啦:

df['资源分配时间'].apply(lambda x : x.split('\xa0')[0])
0 2021-09-01
1 2021-09-01
2 2021-09-01
3 2021-09-01
4 2021-09-01
...
560 2021-09-13
561 2021-09-14
562 2021-09-14
563 2021-09-14
564 2021-09-14
Name: 资源分配时间, Length: 565, dtype: object

事实上,对于这种情况下的分列,最简单其实是不带分隔符,请看:

df['资源分配时间'].apply(lambda x : x.split()[0])
0 2021-09-01
1 2021-09-01
2 2021-09-01
3 2021-09-01
4 2021-09-01
...
560 2021-09-13
561 2021-09-14
562 2021-09-14
563 2021-09-14
564 2021-09-14
Name: 资源分配时间, Length: 565, dtype: object

以上就是分列的操作技巧,但是实际上对于时间类型的数据,pandas有着很丰富且灵活的处理方法,我们来一起看看吧。


2. pandas时间访问器

对于朋友的需求,可以看到被他注释掉的那行代码,嗯,其实用起来会更方便。

被注释掉的技巧

对于长得像时间的数据,pandas可以很好地识别并转化为时间类型,这里我用到的就是pd.to_datetime(),当然还可以用astype做强制转换。

pd.to_datetime(df['资源分配时间'])
0 2021-09-01 16:50:56
1 2021-09-01 16:50:56
2 2021-09-01 16:50:56
3 2021-09-01 16:50:56
4 2021-09-01 16:50:56
...
560 2021-09-13 21:05:14
561 2021-09-14 09:33:02
562 2021-09-14 09:33:02
563 2021-09-14 10:26:42
564 2021-09-14 10:29:58
Name: 资源分配时间, Length: 565, dtype: datetime64[ns]

可以看到,dtype变成了datetime64[ns]时间类型。

对于时间类型数据,pandas提供了一堆方法来玩一玩,简直太方便。对于朋友的需求,我们直接用时间访问器.dt.<属性>既可:

pd.to_datetime(df['资源分配时间']).dt.date
0 2021-09-01
1 2021-09-01
2 2021-09-01
3 2021-09-01
4 2021-09-01
...
560 2021-09-13
561 2021-09-14
562 2021-09-14
563 2021-09-14
564 2021-09-14
Name: 资源分配时间, Length: 565, dtype: object

关于时间访问器,它还有以下属性供大家选择:

# 时间
pd.to_datetime(df['资源分配时间']).dt.time
0 16:50:56
1 16:50:56
2 16:50:56
3 16:50:56
4 16:50:56
...
560 21:05:14
561 09:33:02
562 09:33:02
563 10:26:42
564 10:29:58
Name: 资源分配时间, Length: 565, dtype: object

更多属性如下,大家可以自行演示熟悉:

# 年份
pd.to_datetime(df['资源分配时间']).dt.year
# 月份
pd.to_datetime(df['资源分配时间']).dt.month
# 日
pd.to_datetime(df['资源分配时间']).dt.day
# 小时
pd.to_datetime(df['资源分配时间']).dt.hour
# 分
pd.to_datetime(df['资源分配时间']).dt.minute
# 秒
pd.to_datetime(df['资源分配时间']).dt.second
# 以及更多(这里不展开了)

关于pandas时间序列数据的更多知识,我们后续会开个专题介绍,以上就本次全部内容了,场景很常见,操作技巧在熟悉后就会发现是如此简单。

其实,我们还常见就是将时间戳转化为日期,但是容易遇到时区问题,这方面处理技巧也很多,大家可以参考此前推文《5招学会Pandas数据类型转化》里关于时间类型数据的处理,有详细介绍。

温馨再提示:案例数据在后台回复 955 ,通过 答疑解惑文件夹领取。




推荐阅读


谁才是真正的体育强省!?用python带你一览2021陕西全运会数据找答案!

2021-09-26

答疑解惑:Python爬虫时中文乱码的解决方案

2021-09-18

答疑解惑:用pandas的shift函数解决一个数据处理问题

2021-09-17


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存